package com.jt.www.remote.wx;

import feign.Client;
import feign.Logger;
import feign.hystrix.FallbackFactory;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.net.ssl.*;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

@FeignClient(value = "wx-svc", url = "${remote.wx_url}", configuration = WxConfiguration.class, fallbackFactory = WeChatApi.FeignClientFallbackFactory.class)
public interface WeChatApi {
    @GetMapping(value = "/sns/jscode2session", produces = MediaType.APPLICATION_JSON_VALUE)
    String code2session(@RequestParam("appid") String appId, @RequestParam("secret") String secret, @RequestParam("js_code") String code, @RequestParam("grant_type") String grantType);

    @Component
    class FeignClientFallbackFactory implements FallbackFactory<WeChatApi> {

        public static final org.slf4j.Logger log = LoggerFactory.getLogger(FeignClientFallbackFactory.class);

        @Override
        public WeChatApi create(Throwable throwable) {
            return new WeChatApi() {
                @Override
                public String code2session(String appId, String secret, String code, String grantType) {
                    return null;
                }
            };
        }
    }
}

class WxConfiguration {
    @Bean
    @ConditionalOnMissingBean
    public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, SpringClientFactory clientFactory) throws NoSuchAlgorithmException, KeyManagementException {
        SSLContext ctx = SSLContext.getInstance("SSL");
        X509TrustManager tm = new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
        ctx.init(null, new TrustManager[]{tm}, null);
        return new LoadBalancerFeignClient(new Client.Default(ctx.getSocketFactory(),
                new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                }),
                cachingFactory, clientFactory);
    }

    @Bean
    public Logger.Level logger() {
        return Logger.Level.FULL;
    }
}
